#include "../include/DrawFunctions.h"

// the camera info  
Point3 eye[2];
Point3 lookat[2];
Point3 up[2];
Point3 object_locations[3];
float aspectRatio;
int selected_object;


void GLInit(void)
{
	GLfloat light1_position[] = { 1.0, 10.0, 0.0, 1.0 };
	GLfloat light2_position[] = { 5.0, 10.0, 10.0, 1.0 };
	GLfloat light3_position[] = { -5.0, 10.0, -10.0, 1.0 };
	GLfloat white_light[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat lmodel_ambient[] = {0.1, 0.1, 0.1, 1.0 };

	// initialize the camera
	eye[0].x = 0;
	eye[0].y = 2;
	eye[0].z = 5;
	
	lookat[0].x = 0;
	lookat[0].y = 0;
	lookat[0].z = 0;

	up[0].x = 0;
	up[0].y = 1;
	up[0].z = 0;

	//initialize the hand
	eye[1].x = 0;
	eye[1].y = 3;
	eye[1].z = 3;

	object_locations[0].x = 0;
	object_locations[0].y = 5;
	object_locations[0].z = 0;

	object_locations[1].x = 5;
	object_locations[1].y = 2;
	object_locations[1].z = 3;

	object_locations[2].x = -5;
	object_locations[2].y = 2;
	object_locations[2].z = 3;

	selected_object = 0;

	glEnable(GL_TEXTURE_2D);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	// Really Nice Perspective Calculations
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);


	glEnable(GL_LIGHTING);
	glLightfv(GL_LIGHT0, GL_POSITION, light1_position);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
	
	glLightfv(GL_LIGHT0, GL_POSITION, light2_position);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
	
	glLightfv(GL_LIGHT0, GL_POSITION, light3_position);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
	glEnable(GL_LIGHT0);

}


void DrawObject1(void)
{
	if(draw_object->get_int_val()) {
		glPushMatrix();
		glTranslatef(object_locations[0].x, object_locations[0].y, object_locations[0].z);
		if(selected_object == 1)
			glColor3f(0.7, 0.4, 0.6);
		else
			glColor3f(0.3, 0.7, 0.6);
		switch(live_object_type){
				case 0:
					glutSolidTeapot(1.0);
					break;
				case 1:
					glutSolidCone(1.0, 2.0, 20, 20);
					break;
				case 2:
					glutSolidDodecahedron();
					break;
				case 3:
					glutSolidIcosahedron();
					break;
				case 4:
					glutSolidSphere(1.0, 20, 20);
					break;
				case 5:
					glutSolidTorus(1.0, 2.0, 20, 20);
					break;
		}
		glPopMatrix();
	}
}


void DrawObject2(void)
{
	if(draw_object->get_int_val()) {
		glPushMatrix();
		glTranslatef(object_locations[1].x, object_locations[1].y, object_locations[1].z);
		if(selected_object == 2)
			glColor3f(0.7, 0.4, 0.6);
		else
			glColor3f(0.3, 0.7, 0.75);
		glutSolidDodecahedron();
		glPopMatrix();
	}
}

void DrawObject3(void)
{
	if(draw_object->get_int_val()) {
		glPushMatrix();
		glTranslatef(object_locations[2].x, object_locations[2].y, object_locations[2].z);
		if(selected_object == 3)
			glColor3f(0.7, 0.4, 0.6);
		else
			glColor3f(0.3, 0.7, 0.9);
		glutSolidCone(1.0, 2.0, 20, 20);
		glPopMatrix();
	}
}

void DrawFloor() {
	if(draw_floor->get_int_val()) {
		int check = 0;
		glPushMatrix();
		glTranslatef(0.0, -10.0, 0.0);
		for(int i = -100; i < 100; i += 1) {
			check++;
			for(int j = -100; j < 100; j += 1) {
				check++;
				if(check % 2) {
					glColor3f(0, 0, 1);
				}
				else {
					glColor3f(0, 1, 0);
				}
				glBegin(GL_TRIANGLE_FAN);
				glVertex3f(j - 0.5, 0, i - 0.5);
				glVertex3f(j + 0.5, 0, i - 0.5);
				glVertex3f(j + 0.5, 0, i + 0.5);
				glVertex3f(j - 0.5, 0, i + 0.5);
				glEnd();
			}
		}
		glPopMatrix();
	}

}

void DrawHand()
{
		glPushMatrix();
		glTranslatef(eye[1].x, eye[1].y, eye[1].z);
		glColor3f(0.9, 0.3, 0.3);
		glutSolidSphere(0.1, 20, 20);
		glPopMatrix();

		//draw the lookat line
		glPushMatrix();
		glBegin(GL_LINES);
			glVertex3f(eye[1].x, eye[1].y, eye[1].z);
			glVertex3f(lookat[1].x, lookat[1].y, lookat[1].z);
		glEnd();
		glPopMatrix();					
}

void SetProjection(stereo_t stereo)
{
	float frustumShift = live_IOD_trans / 2 * live_nearplane_trans / live_focal_length;
	float top = tan(live_FOVY_trans/2)*live_nearplane_trans;
	float bottom = -1 * top;
	float left = bottom * aspectRatio;
	float right = top * aspectRatio;

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	switch(live_projection_type) {
		case 0: //glOrtho
			glOrtho(-1, 1, -1, 1, live_nearplane_trans, live_farplane_trans);
			break;
		case 1: //gluPerspective
			gluPerspective(90.0, 1.0, live_nearplane_trans, live_farplane_trans);
			break;
		case 2: //glFrustum
			if(stereo == STEREO_RIGHT) {
				glFrustum(left - frustumShift, right - frustumShift, bottom, top, live_nearplane_trans, live_farplane_trans);
			} else if(stereo == STEREO_LEFT) {
				glFrustum(left + frustumShift, right + frustumShift, bottom, top, live_nearplane_trans, live_farplane_trans);
			} else {
				glFrustum(-1, 1, -1, 1, live_nearplane_trans, live_farplane_trans);
			}
			break;
	}
}

void SetCamera(stereo_t stereo)
{
	// camera transform
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	if(stereo == STEREO_RIGHT) {
		gluLookAt(eye[0].x + live_IOD_trans / 2.0, eye[0].y, eye[0].z, lookat[0].x, lookat[0].y, lookat[0].z, 0, 1, 0);
	} else if (stereo == STEREO_LEFT) {
		gluLookAt(eye[0].x - live_IOD_trans / 2.0, eye[0].y, eye[0].z, lookat[0].x, lookat[0].y, lookat[0].z, 0, 1, 0);
	} else {
		gluLookAt(eye[0].x, eye[0].y, eye[0].z, lookat[0].x, lookat[0].y, lookat[0].z, up[0].x, up[0].y, up[0].z);
	}
}
